package com.jieli.bt.att.util

import android.content.Context
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import androidx.core.content.FileProvider
import com.jieli.logcat.JL_Log
import java.io.File

/**
 * FileUtil
 * @author zqjasonZhong
 * @since 2024/9/20
 * @email zhongzhuocheng@zh-jieli.com
 * @desc 文件工具类
 */
object FileUtil {

    private val TAG = FileUtil::class.simpleName

    const val DIR_BLUETOOTH_ATT = "BT_ATT"

    /**
     * 创建文件夹路径
     *
     * @param context  上下文
     * @param dirNames 文件夹名称
     * @return 文件夹路径
     */
    fun createFilePath(context: Context?, vararg dirNames: String?): String {
        if (context == null || dirNames.isEmpty()) return ""
        var file = context.getExternalFilesDir(null)
        if (file == null || !file.exists()) return ""
        var filePath = StringBuilder(file.path)
        if (filePath.toString().endsWith("/")) {
            filePath = StringBuilder(filePath.substring(0, filePath.lastIndexOf("/")))
        }
        try {
            for (dirName in dirNames) {
                filePath.append("/").append(dirName)
                file = File(filePath.toString())
                if (!file.exists() || file.isFile) { //文件不存在
                    if (!file.mkdir()) {
                        JL_Log.w(
                            TAG, "createFilePath",
                            "create dir failed. filePath = $filePath"
                        )
                        break
                    }
                }
            }
        } catch (ignore: Exception) {
        }
        return filePath.toString()
    }

    /**
     * 格式化文件大小
     * @param fileSize long 文件大小
     * @return String 格式化内容
     */
    fun formatFileSize(fileSize: Long): String {
        if (fileSize < 1024) {
            return "$fileSize Bytes"
        }
        var value = fileSize / 1024f
        if (value < 1024) {
            return BluetoothUtil.formatString("%.1f KB", value)
        }
        value /= 1024f
        if (value < 1024) {
            return BluetoothUtil.formatString("%.1f MB", value)
        }
        value /= 1024f
        return BluetoothUtil.formatString("%.1f GB", value)
    }

    /**
     * 是否分区存储
     */
    fun isScopedStorage(): Boolean =
        Environment.getExternalStorageDirectory().equals(Environment.getRootDirectory())

    /**
     * 获取文件夹输出路径
     */
    fun getDownloadFilePath(fileName: String): String =
        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).path + File.separator + DIR_BLUETOOTH_ATT + File.separator + fileName

    /**
     * 判断文件是否Download文件夹
     *
     * @param context Context 上下文
     * @param fileName String 文件名
     * @return Boolean 结果
     */
    fun isFileInDownload(context: Context, fileName: String): Boolean {
        if (!PermissionUtil.hasReadStoragePermission(context)) return false
        val selection = MediaStore.Downloads.DISPLAY_NAME + " = ?"
        val args = arrayOf(fileName)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            try {
                context.contentResolver.query(
                    MediaStore.Downloads.EXTERNAL_CONTENT_URI,
                    null,
                    selection,
                    args,
                    null
                )?.let { cursor ->
                    var result = false
                    while (cursor.moveToFirst()) {
                        val name =
                            cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Downloads.DISPLAY_NAME))
                        result = name == fileName
                        if (result) break
                    }
                    cursor.close()
                    if (result) return true
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
        try {
            return File(getDownloadFilePath(fileName)).exists()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return false
    }

    fun getDownloadDirectoryUri(): Uri =
        Uri.parse("content://com.android.externalstorage.documents/tree/primary%3ADownload")

    fun getUriByPath(context: Context, path: String): Uri? =
        if (path.isBlank()) null else getUriByFile(context, File(path))

    fun getUriByFile(context: Context, file: File): Uri? {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            FileProvider.getUriForFile(
                context, context.packageName + ".provider",
                file
            )
        } else {
            Uri.fromFile(file)
        }
    }

    fun deleteFile(file: File): Boolean {
        if (!file.exists()) return false
        if (file.isFile) {
            return file.delete()
        }
        val childFiles = file.listFiles()
        if (null == childFiles || childFiles.isEmpty()) {
            //空文件夹，直接删除
            return file.delete()
        }
        for (child in childFiles) {
            if (!deleteFile(child)) {
                //删除文件失败
                return false
            }
        }
        //已删除子文件，空文件夹，删除
        return file.delete()
    }
}